package dnamap;
/**
 * Deal with basic operations of DNA bases, such as 
 * transform text base sequences into numeric format
 * and transform numeric format from one to another 
 * <p>
 * This class also stores all the necessary constants
 * for other DNA processing classes. 
 *
 *  
                          
@author Yunxiao
 *  
                          
@version 1.0
 *  
 */
public class Nucleotide {
	static String basecode = new String("ATGC");
    static int codonlen = 3;
    static int codonnum = 64;
    static int alphalen = 99;
    static int dbaselen = 4;
    static int baselen = 2;
    static int dbasemask = 0x0f;
    static int basemask = 0x03;
    /**
     * To get numeric representation of a nucleotide.
     * Only 2-bit format is accepted.
     *  
     *  @param x the nucleotide to be replaced by numeric.
     *           case-insensitive
     *           
     *  @return return the numeric representation value
     *  
     */    
	public int codelookup(char x)                   //from char to numeric base
	{
		switch(Character.toUpperCase(x))
		{
			case 'A': return 0;
	        case 'T': return 1;
	        case 'U': return 1;
	        case 'G': return 2;
	        case 'C': return 3;
		}
		return -1;
	}
	/**
	 * get the degenerative representation of a nucleotide
	 *  
	 *  @param x  the nucleotide to look up. case-insensitive
	 *  
	 *  @return   the degenerative numeric representation
	 *  
	 */
	public int dcodelookup(char x)					//from char to degenerate
	{		
	    switch(Character.toUpperCase(x))
	    {
	        case 'A': return 0x8;
	        case 'T': return 0x4;
	        case 'U': return 0x4;
	        case 'G': return 0x2;
	        case 'C': return 0x1;
	        case 'K': return 0x6;
	        case 'N': return 0xF;
	        case 'M': return 0x9;
	        case 'R': return 0xA;
	        case 'Y': return 0x5;
	        case 'S': return 0x3;
	        case 'W': return 0xC;
	        case 'B': return 0x7;
	        case 'V': return 0xB;
	        case 'H': return 0xD;
	        case 'D': return 0xE;
	        case 'X': return 0xF;
	        case '.': return 0x0;
	    }
	    return 0;	
	}
	/**
	 * Transform degenerative representation to basic numeric
	 * Taken a codon triplet as a unit
	 *  
	 *  @param x  degenerative representation of a codon triplet
	 *  
	 *  @return   numeric codon triplet
	 *  
	 */	
	int dcodon2bcodon(int x)						//from degenerate to numeric
	{
		int res = 0;
	    for(int i = 0; i < codonlen; i++)
	    {
	        for(int j = 0; j < dbaselen; j++)
	        {
	            if((x & (01 << (j + i * dbaselen))) != 0)
	            {
	                res |= (dbaselen - j - 1) << (baselen * i);
	                break;
	            }
	        }
	    }
	    return res;
	}
	/**
	 * get the degenerative representation of a nucleotide
	 * Nucleotide is in numeric format
	 *  
	 *  @param x  the nucleotide to look up, numeric format
	 *  
	 *  @return   the degenerative numeric representation
	 *  
	 */
	int bcode2dcode(int x)							//from numeric to degenerate
	{
		 return 01 << (3 - x);	
	}
	/**
	 * Transform numeric format to degenerative
	 * Taken triplet as a unit
	 *  
	 *  @param x  numeric codon triplet
	 *  
	 *  @return   degenerative codon triplet
	 *  
	 */
	int bcodon2dcodon(int x)						//From numeric to degenerate
	{
		int dcodon = 0, bcodon = x;
	    for(int i = 0 ; i < codonlen; i++)
	    {
	        dcodon |= bcode2dcode(bcodon & 0x03) << (i * dbaselen);	        
	        bcodon >>= 2;
	    }
	    return dcodon;	
	}	
	/**
	 * Transform codon char sequence into numeric format
	 * Taken triplet as a unit.
	 *  
	 *  @param x  string of a triplet
	 *  
	 *  @return   numeric format of a codon triplet
	 *  
	 */
	int ccodon2bcodon(String x)						//from char to numeric
	{
		int ncodon = 0;
		for(int i = 0; i < codonlen; i++)
        {
            int bcode = codelookup(x.charAt(i));
            if(bcode >= 0)
            {
                ncodon |= bcode << ((codonlen - i - 1) * 2);
            }
            else
            {
                ncodon = -1;
                break;
            }
        }
		return ncodon;
	}
}


